import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.table.AbstractTableModel;

public class TableModel extends AbstractTableModel 
{
	public static final int IP_INDEX =0;
	public static final int HOST_INDEX = 1;
    public static final int MONITOR_TYPE_INDEX = 2;
    public static final int VALUE_INDEX = 3;
    public static final int PARAM_INDEX = 4;
	private final static String[] COLUMN_NAMES = {"IP","Host","Monitor Type","Value","Parameter"};
	private Map<String,MonitorData> m_map;
	
	public TableModel()
	{
		m_map = new HashMap<String, MonitorData>();
	}
	
	@Override
	public int getColumnCount() {
		return COLUMN_NAMES.length;
	}

	@Override
	public int getRowCount() {
		return m_map.size();
	}

	// TODO: tal - check this function 
	@Override
	public Object getValueAt(int rowIndex, int colIndex) 
	{	
		MonitorData row = getAllRows().get(rowIndex);
		switch(colIndex)
		{
			case IP_INDEX:
				return row.getIP();
			case HOST_INDEX:
				return row.getHost();
			case MONITOR_TYPE_INDEX:
				return row.getMonitorDataType().toString();
			case VALUE_INDEX:
				return Integer.parseInt(((row.getValue() == null) ||  (row.getValue() == "")) ? "0" : row.getValue());
			case PARAM_INDEX:
				return row.getParameter();
		}
		return null;
	}
	
	@Override
	public String getColumnName(int index)
	{
		return COLUMN_NAMES[index];
	}
	
	@Override
	public boolean isCellEditable(int rowIndex, int columnIndex) 
	{
		return false;
	}
	
	public MonitorData getRow(int rowIndex)
	{
		if (rowIndex < 0 || rowIndex >= m_map.size())
			return null;
		return getAllRows().get(rowIndex);
	}

	public List<MonitorData> getAllRows()
	{
		return Collections.list(Collections.enumeration(m_map.values()));
	}

	public boolean addRow(MonitorData data) 
	{
		String key = createKey(data);
		int index = getRowCount();
		
		// If the row already exists in the table, update it
		if(m_map.containsKey(key))
		{
			MonitorData oldMonitorData = m_map.get(key);
			index = getAllRows().indexOf(oldMonitorData);
		}
		
		// Update data structure
		m_map.put(createKey(data), data);
		// fire event
		fireTableRowsInserted(index, index);
		return true;
	}
	
	public boolean updateRow(MonitorData newData)
	{
		String key = createKey(newData);
		MonitorData oldData = m_map.get(key);
		if(oldData == null)
			return false;
		
		// Get row index
		int rowIndex = getAllRows().indexOf(oldData);
		 
		oldData.setTimeStamp(newData.getTimeStamp());
		oldData.setValue(newData.getValue());
		oldData.setIsAlive(newData.getIsAlive());
		
		//fireTableCellUpdated(rowIndex, VALUE_INDEX);
		fireTableRowsUpdated(rowIndex, rowIndex);
		return true;
	}
	
	private String createKey(MonitorData monitorData)
	{
		return monitorData.getIP() + "|" + monitorData.getMonitorDataType().toString();
	}
	
	public boolean removeRow(MonitorData data)
	{
		String key = createKey(data);
		int index = getAllRows().indexOf(data);
		if(index == -1)
			return false;
		if(m_map.remove(key) == null)
			return false;
			
		fireTableRowsDeleted(index, index);
		return true;
	}
}
